package com.unlcn.ils.wms.backend.service.inbound.impl;

import cn.huiyunche.commons.exception.BusinessException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.unlcn.ils.wms.backend.bo.inboundBO.WmsRepairBO;
import com.unlcn.ils.wms.backend.enums.*;
import com.unlcn.ils.wms.backend.service.inbound.WmsRepairService;
import com.unlcn.ils.wms.backend.util.ObjectToMapUtils;
import com.unlcn.ils.wms.base.businessDTO.inbound.WmsRepairQueryDTO;
import com.unlcn.ils.wms.base.mapper.additional.WmsInboundRepairExtMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsInboundOrderMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsInboundRepairMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsInventoryLocationMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysUserMapper;
import com.unlcn.ils.wms.base.model.inbound.WmsInboundOrder;
import com.unlcn.ils.wms.base.model.inbound.WmsInboundRepair;
import com.unlcn.ils.wms.base.model.stock.WmsInventoryLocation;
import com.unlcn.ils.wms.base.model.stock.WmsInventoryLocationExample;
import com.unlcn.ils.wms.base.model.sys.SysUser;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by DELL on 2017/8/7.
 */
@Service
public class WmsRepairServiceImpl implements WmsRepairService {
    private Logger LOGGER = LoggerFactory.getLogger(AsnOrderServiceImpl.class);
    @Autowired
    private WmsInboundRepairExtMapper wmsInboundRepairExtMapper;

    @Autowired
    private WmsInboundRepairMapper wmsInboundRepairMapper;

    @Autowired
    private WmsInboundOrderMapper wmsInboundOrderMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private WmsInventoryLocationMapper wmsInventoryLocationMapper;

    /**
     * 查询维修单列表
     *
     * @param wmsRepairQueryDTO
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> getListWmsRepairBO(WmsRepairQueryDTO wmsRepairQueryDTO) throws Exception {
        LOGGER.info("WmsRepairServiceImpl.getListWmsRepairBO param{}", wmsRepairQueryDTO);
        if (Objects.equals(wmsRepairQueryDTO, null)) {
            throw new IllegalArgumentException("分页参数不能为空");
        }
        if (StringUtils.isBlank(wmsRepairQueryDTO.getRpWhCode())) {
            throw new BusinessException("仓库code为空!");
        }
        //if (!(WhCodeEnum.JM_CS.getValue().equals(wmsRepairQueryDTO.getRpWhCode())
        //        || WhCodeEnum.JM_XY.getValue().equals(wmsRepairQueryDTO.getRpWhCode())))
        //    throw new BusinessException("该仓库不支持此操作!");

        Map<String, Object> resultMap = Maps.newHashMap();
        //起始记录
        wmsRepairQueryDTO.setLimitStart((wmsRepairQueryDTO.getStartIndex() < 0) ? 0
                : wmsRepairQueryDTO.getStartIndex());
        wmsRepairQueryDTO.setLimitEnd(wmsRepairQueryDTO.getPageSize());
        Map<String, Object> paramMap = ObjectToMapUtils.objectToMap(wmsRepairQueryDTO);
        //排序
        paramMap.put("order", StringUtils.isBlank(wmsRepairQueryDTO.getOrder()) ? " gmt_create desc , rp_id desc"
                : wmsRepairQueryDTO.getOrder());
        paramMap.put("rpWhCode", wmsRepairQueryDTO.getRpWhCode());
        List<WmsInboundRepair> infos = wmsInboundRepairExtMapper.queryForList(paramMap);
        List<WmsRepairBO> bos = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(infos)) {
            infos.stream()
                    .filter(v -> !Objects.equals(v, null))
                    .forEach(v -> {
                        WmsRepairBO bo = new WmsRepairBO();
                        BeanUtils.copyProperties(v, bo);
                        bos.add(bo);
                    });
            resultMap.put("wmsRepairList", bos);
        }
        wmsRepairQueryDTO.setPageNo(wmsRepairQueryDTO.getStartIndex());
        wmsRepairQueryDTO.setPageSize(wmsRepairQueryDTO.getPageSize());
        wmsRepairQueryDTO.setTotalRecord(wmsInboundRepairExtMapper.queryForCount(paramMap));
        resultMap.put("wmsRepairQueryDTO", wmsRepairQueryDTO);
        return resultMap;
    }

    /**
     * 提交维修单
     *
     * @param bo
     * @param whCode
     * @param userId
     */
    @Override
    public void updateSubmitRepair(WmsRepairBO bo, String whCode, String userId) throws Exception {
        LOGGER.info("WmsRepairServiceImpl.updateSubmitRepair param{}", bo);
        if (Objects.equals(bo, null)) {
            throw new BusinessException("传入参数不能为空!");
        }
        if (StringUtils.isBlank(bo.getRpRepairParty()))
            throw new BusinessException("维修单位不能为空!");
        if (Objects.equals(bo.getRpEstimatedEndTime(), null))
            throw new BusinessException("预计维修完成时间不能为空!");
        if (Objects.equals(bo.getRpId(), null))
            throw new BusinessException("维修Id不能为空!");
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空");
        if (StringUtils.isBlank(userId))
            throw new BusinessException("用户Id不能为空!");
        //if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode)))
        //    throw new BusinessException("该仓库不支持此操作!");

        //更新提交维修单
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(Integer.valueOf(userId));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        WmsInboundRepair repair = wmsInboundRepairMapper.selectByPrimaryKey(bo.getRpId());
        if (StringUtils.isNotBlank(repair.getRpWhCode()) &&
                !whCode.equals(repair.getRpWhCode()))
            throw new BusinessException("该用户不具备该仓库操作权限");
        if (String.valueOf(WmsRepairStatusEnum.WMS_REPAIR_STATUS_ING.getValue()).equals(repair.getRpStatus())
                || String.valueOf(WmsRepairStatusEnum.WMS_REPAIR_STATUS_COMPLETE.getValue()).equals(repair.getRpStatus())) {
            throw new BusinessException("该维修单已经进行过该操作");
        }
        repair.setRpRepairParty(bo.getRpRepairParty());//维修单位
        repair.setRpId(bo.getRpId());
        Date date = new Date();//当前时间
        repair.setGmtUpdate(date);
        repair.setModifyUserId(userId);
        repair.setRpStartDate(sdf.format(date));
        if (sysUser != null && StringUtils.isNotBlank(sysUser.getName())) {
            repair.setModifyUserName(sysUser.getName());
        }
        if (StringUtils.isNotBlank(bo.getRemark())) {
            repair.setRemark(bo.getRemark());
        }
        repair.setRpStatus(String.valueOf(WmsRepairStatusEnum.WMS_REPAIR_STATUS_ING.getValue()));
        repair.setRpEstimatedEndTime(bo.getRpEstimatedEndTime());
        //看预计维修完成时间是否满足两个小时内--针对出库维修
        if (StringUtils.isNotBlank(repair.getRpInandoutType())
                && String.valueOf(WmsRepairInAndOutTypeEnum.OUTBOUND_REPAIR.getValue()).equals(repair.getRpInandoutType())) {
            long now = date.getTime();
            long endTime = bo.getRpEstimatedEndTime().getTime();
            if (now > endTime) {
                throw new BusinessException("预计维修完成时间小于当前时间");
            }
            long diff = (endTime - now) / (1000 * 60 * 60);//转换差异时间到小时
            if (diff > 2) {
                //完成时间大于两个小时--维修出库的时候释放库存
                repair.setRepairInspectPlace(String.valueOf(WmsRepairInspectPlaceEnum.INBOUND_PLACE.getValue()));
            }
        }
        if (StringUtils.isNotBlank(repair.getRpInandoutType())
                && String.valueOf(WmsRepairInAndOutTypeEnum.INBOUND_REPAIR.getValue()).equals(repair.getRpInandoutType())) {
            //入库维修--只能时入库区验车
            repair.setRepairInspectPlace(String.valueOf(WmsRepairInspectPlaceEnum.INBOUND_PLACE.getValue()));
        }
        repair.setRpStartDate(sdf.format(date));
        repair.setRpInOutStatus(RepairInOutStatusEnum.NO_SEND.getCode());
        wmsInboundRepairMapper.updateByPrimaryKeySelective(repair);
        //更新库存状态为维修锁定
        WmsInventoryLocationExample locationExample = new WmsInventoryLocationExample();
        locationExample.createCriteria().andInvlocVinEqualTo(repair.getRpVin())
                .andStatusEqualTo(InventoryLocationStatusEnum.DEST_LOCK_20.getCode())
                .andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
        WmsInventoryLocation inventoryLocation = new WmsInventoryLocation();
        if (sysUser != null && StringUtils.isNotBlank(sysUser.getName())) {
            inventoryLocation.setModifyUserName(sysUser.getName());
        }
        inventoryLocation.setModifyUserId(userId);
        inventoryLocation.setStatus(InventoryLocationStatusEnum.REPAIR_LOCK_40.getCode());
        inventoryLocation.setGmtUpdate(date);
        wmsInventoryLocationMapper.updateByExampleSelective(inventoryLocation, locationExample);
    }


    /**
     * 打印维修单
     *
     * @param bo
     * @param whCode
     * @param userId
     * @throws Exception
     */
    @Override
    public HashMap<String, Object> updatePrintRepair(WmsRepairBO bo, String whCode, String userId) throws Exception {
        LOGGER.info("WmsRepairServiceImpl.updateSubmitRepair param{}{}{}", bo, whCode, userId);
        if (Objects.equals(bo, null))
            throw new BusinessException("传入参数不能为空!");
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库Code不能为空!");
        if (StringUtils.isBlank(userId))
            throw new BusinessException("用户id不能为空!");
        if (bo.getRpId() == null)
            throw new BusinessException("请选择要打印的维修单!");
        //打印维修单条形码--需要显示条形码数字
        HashMap<String, Object> resultMap = Maps.newHashMap();
        WmsInboundRepair repair = wmsInboundRepairMapper.selectByPrimaryKey(bo.getRpId());
        if (repair != null) {
            if (StringUtils.isNotBlank(repair.getRpStatus())
                    && String.valueOf(WmsRepairStatusEnum.WMS_REPAIR_STATUS_NOT_HANDLE.getValue()).equals(repair.getRpStatus())) {
                throw new BusinessException("该维修单未提交维修,不能进行该操作!");
            }
            if (String.valueOf(WmsRepairInAndOutTypeEnum.INBOUND_REPAIR.getValue()).equals(bo.getRpInandoutType())) {
                throw new BusinessException("只能打印备料异常维修单");
            }
            String contents = repair.getRpRepairNo();
            if (StringUtils.isBlank(contents))
                throw new BusinessException("维修出库单号不存在!");
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.CODE_128, 200, 50, null);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
            MatrixToImageWriter.writeToStream(bitMatrix, "png", bos);
            Base64 base64 = new Base64();
            String img = base64.encodeToString(bos.toByteArray());
            //BASE64Encoder base64Encoder = new BASE64Encoder();
            //String img = base64Encoder.encode(bos.toByteArray());
            resultMap.put("img", img);
            resultMap.put("repair", repair);
        }
        return resultMap;
    }


    @Override
    public void addWmsRepair(WmsRepairBO wmsRepairBO) {
        WmsInboundRepair wmsInboundRepair = new WmsInboundRepair();
        BeanUtils.copyProperties(wmsRepairBO, wmsInboundRepair);
        wmsInboundRepairMapper.insert(wmsInboundRepair);
    }

    @Override
    public boolean updateWmsRepair(WmsRepairBO wmsRepairBO) {
        return false;
    }


    @Override
    public void submitAfterCheckCopyAndAdd(WmsRepairBO wmsRepairBO) {
        //更新当前一条的维修状态
        WmsInboundRepair wmsInboundRepair = new WmsInboundRepair();
        BeanUtils.copyProperties(wmsRepairBO, wmsInboundRepair);
        wmsInboundRepair.setRpStatus(String.valueOf(WmsRepairStatusEnum.WMS_REPAIR_STATUS_COMPLETE.getValue()));
        wmsInboundRepairMapper.updateByPrimaryKey(wmsInboundRepair);

        //修改入库单检验状态
        WmsInboundOrder wmsInboundAsnOrder = new WmsInboundOrder();
        wmsInboundAsnOrder.setOdId(wmsRepairBO.getRpOdId() != null ? Long.valueOf(wmsRepairBO.getRpOdId()) : 0L);
        wmsInboundAsnOrder.setOdCheckResult(wmsRepairBO.getRpCheckResult());
        wmsInboundAsnOrder.setOdCheckDesc(wmsRepairBO.getRemark());
        wmsInboundOrderMapper.updateByPrimaryKeySelective(wmsInboundAsnOrder);
    }

    @Override
    public void submitAfterCheck(WmsRepairBO wmsRepairBO) {
        if ("10".equals(wmsRepairBO.getRpRepairResult())) {//维修结果为合格
            WmsInboundRepair wmsInboundRepair = new WmsInboundRepair();
            BeanUtils.copyProperties(wmsRepairBO, wmsInboundRepair);
            wmsInboundRepair.setRpStatus(String.valueOf(WmsRepairStatusEnum.WMS_REPAIR_STATUS_COMPLETE.getValue()));//维修状态
            wmsInboundRepair.setRpCheckResult(String.valueOf(AsnOrderCheckEnum.ASNORDER_PASS.getValue()));//维修结果
            wmsInboundRepairMapper.updateByPrimaryKeySelective(wmsInboundRepair);
            //修改入库单检验状态
            WmsInboundOrder wmsInboundAsnOrder = new WmsInboundOrder();
            wmsInboundAsnOrder.setOdId(wmsRepairBO.getRpOdId() != null ? Long.valueOf(wmsRepairBO.getRpOdId()) : 0L);
            wmsInboundAsnOrder.setOdCheckResult(wmsRepairBO.getRpCheckResult());
            wmsInboundAsnOrder.setOdCheckDesc(wmsRepairBO.getRemark());
            wmsInboundOrderMapper.updateByPrimaryKeySelective(wmsInboundAsnOrder);

        } else if ("20".equals(wmsRepairBO.getRpRepairResult())) {//维修结果为不合格
            WmsInboundRepair wmsInboundRepair = new WmsInboundRepair();
            BeanUtils.copyProperties(wmsRepairBO, wmsInboundRepair);
            wmsInboundRepair.setRpStatus(String.valueOf(WmsRepairStatusEnum.WMS_REPAIR_STATUS_ING.getValue()));
            wmsInboundRepairMapper.insert(wmsInboundRepair);
        }
    }

    @Override
    public WmsRepairBO getRepairById(String rpId) {
        WmsInboundRepair wmsInboundRepair = wmsInboundRepairMapper.selectByPrimaryKey(Long.valueOf(rpId));
        WmsRepairBO wmsRepairBO = new WmsRepairBO();
        BeanUtils.copyProperties(wmsInboundRepair, wmsRepairBO);
        return wmsRepairBO;
    }


}
